package ekahau.positioning.client.model;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.eclipse.swt.browser.LocationListener;



import com.ekahau.engine.sdk.Device;
import com.ekahau.engine.sdk.DeviceLocation;
import com.ekahau.engine.sdk.EngineException;
import com.ekahau.engine.sdk.IDeviceLocationListener;
import com.ekahau.engine.sdk.PositioningEngine;
import com.ekahau.engine.sdk.event.BatteryEvent;
import com.ekahau.engine.sdk.event.CommandsSentEvent;
import com.ekahau.engine.sdk.event.DeviceInfoEvent;
import com.ekahau.engine.sdk.event.EngineEvent;
import com.ekahau.engine.sdk.event.IEngineEventListener;
import com.ekahau.engine.sdk.event.LocationEstimate;
import com.ekahau.engine.sdk.event.MapEvent;
import com.ekahau.engine.sdk.event.ModelEvent;
import com.ekahau.engine.sdk.event.ScanEvent;
import com.ekahau.engine.sdk.event.SiteEvent;
import com.ekahau.engine.sdk.event.TagGroupEvent;
import com.ekahau.engine.sdk.event.TemperatureEvent;
import com.ekahau.engine.sdk.event.ZoneEvent;

import ekahau.positioning.client.model.EkahauTag.EVENT_TYPE;

public class EkahauPositionEngineClient {

	//Vector<EkahauTag> tags = new Vector<EkahauTag>();
	private HashMap iTags = new HashMap<String, EkahauTag>();
	private String host = "130.240.233.27";
	private int port = 8550;
	private String userName = "isaac";
	private String password = "albert";
	private IModelChanged modelChangedListener ;
	public EkahauPositionEngineClient() {
		PositioningEngine engine = new PositioningEngine(host,port,userName,password);
		
        List devices = null;
		try {
			devices = engine.findDevices();
		} catch (EngineException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
        engine.addLocationListener(new IDeviceLocationListener() {
			
			@Override
			public void newDeviceLocation(DeviceLocation arg0) {
				
				// Sometimes receives bad streams and throws an exception
				try{
					
					String mac = arg0.getMAC();
					EkahauTag tag = (EkahauTag)iTags.get(mac);
					if(tag == null || tag.getZoneName() != null 
								&& arg0.getZoneName()!= null &&
								tag.getZoneName().compareToIgnoreCase(arg0.getZoneName()) == 0)
						return;
					
					tag.setX(arg0.getX());
					tag.setY(arg0.getY());
					tag.setAddress(arg0.getMAC());
					tag.setDeviceId(arg0.getDeviceId());
					tag.setName(arg0.getName());
					tag.setZoneId(arg0.getZoneId());
					
					tag.setZoneName(arg0.getZoneName());
					tag.setEventType(EVENT_TYPE.LOCAION_CHANED);
					if(modelChangedListener!= null)
						modelChangedListener.modelChanged(tag);
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			
			@Override
			public void connectionClosed(Exception arg0) {
				// TODO Auto-generated method stub
				
			}
		});

        engine.addEventListener(new IEngineEventListener() {
			
			@Override
			public void newZoneExitedEvent(ZoneEvent arg0, Device arg1,
					LocationEstimate arg2) {
//				String mac = arg1.getMAC();
//				EkahauTag tag = (EkahauTag)iTags.get(mac);
//				tag.setName(arg1.getName());
//				tag.setZoneId(arg0.getZoneId());
//				tag.setZoneName(arg0.getZoneName());
//				tag.setEventType(EVENT_TYPE.ZONE_EXITED);
//				modelChangedListener.modelChanged(tag);
				
			}
			
			@Override
			public void newZoneEnteredEvent(ZoneEvent arg0, Device arg1,
					LocationEstimate arg2) {
				
				try{	
					String mac = arg1.getMAC();
					EkahauTag tag = (EkahauTag)iTags.get(mac);
					if(tag.getZoneName().compareToIgnoreCase(arg0.getZoneName()) == 0)
						return;
					tag.setName(arg1.getName());
					tag.setZoneId(arg0.getZoneId());
					tag.setZoneName(arg0.getZoneName());
					tag.setX(arg2.getX());
					tag.setY(arg2.getY());
					tag.setEventType(EVENT_TYPE.NEW_ZONE_ENTERED);
					if(modelChangedListener != null)
						modelChangedListener.modelChanged(tag);
					
				}catch(Exception e){
					e.printStackTrace();
				}
				
			}
			
			@Override
			public void newTemperatureEvent(TemperatureEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newTagGroupChangedEvent(TagGroupEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newSiteExitedEvent(SiteEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newSiteEnteredEvent(SiteEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newScanEvent(ScanEvent arg0, Device arg1, LocationEstimate arg2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newMapExitedEvent(MapEvent arg0, Device arg1,
					LocationEstimate arg2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newMapEnteredEvent(MapEvent arg0, Device arg1,
					LocationEstimate arg2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newEvent(EngineEvent arg0, Device arg1, LocationEstimate arg2) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newDeviceInfoChangedEvent(DeviceInfoEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newDeviceDeletedEvent(EngineEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newCommandsSentEvent(CommandsSentEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newBatteryLowEvent(BatteryEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newBatteryHighEvent(BatteryEvent arg0, Device arg1) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void newActiveModelChangedEvent(ModelEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void connectionClosed(Exception arg0) {
				// TODO Auto-generated method stub
				
			}
		}); 

        
        Iterator it = devices.iterator();
        
        while (it.hasNext()) {
        	EkahauTag tag = new EkahauTag();
            DeviceLocation d = (DeviceLocation) it.next();
           
            Integer x,y,zoneId=0;
            
            x = d.getX();
            y=d.getY();
            zoneId = d.getZoneId();
            
            if(x == null){
            	x = -1;
            }
            if(y == null){
            	y=-1;
            }
            if(zoneId == null){
            	zoneId=-1;
            }
            
            
	            tag.setX(x);
	            tag.setY(y);
	            tag.setName(d.getName());
	            tag.setAddress(d.getMAC());
	            tag.setZoneId(zoneId);
	            tag.setZoneName(d.getZoneName());
	            tag.setDeviceId(d.getDeviceId());
	            //tags.add(tag);
	            iTags.put(d.getMAC(), tag);
          
                       
        }
        try {
			engine.startTracking();
		} catch (EngineException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	
	}
	
	public Collection getTags(){
	 	   return iTags.values();
	}
	
	public void addModelChangedListener(IModelChanged modelChanged){
		modelChangedListener = modelChanged ;
	}
	public static void main(String[] args){
		
			EkahauPositionEngineClient client = new EkahauPositionEngineClient();
			Collection<EkahauTag> tags = client.getTags();
			Iterator<EkahauTag> i = tags.iterator();
			while(i.hasNext()){
				
				EkahauTag tag = i.next();
				System.out.println("Name: " + tag.getName());
				System.out.println("Mac Address: " + tag.getAddress());
				System.out.println("X Pos: " + tag.getX());
				System.out.println("Y Pos: " + tag.getY());
				System.out.println("Zone ID: " + tag.getZoneId());
				System.out.println("Zone Name: " + tag.getZoneName());
				
				
			}
		
	}
	
}
